package la.renzhen.rtpt.config.source;

import la.renzhen.rtpt.config.ConfigurationSource;
import la.renzhen.rtpt.config.source.template.RestTemplateSelector;
import la.renzhen.rtpt.spring.boot.RTPTProperties;
import org.springframework.retry.annotation.Retryable;
import org.springframework.util.StringUtils;
import org.springframework.web.client.RestTemplate;

import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

/**
 * RTPT实现的中心配置<p>
 *
 * @author <a href="mailto:zhouhaichao@2008.sina.com">haiker</a>
 * @version 09/05/2018 11:17 AM
 */
public class AdminCenterSource implements ConfigurationSource {

    /**
     * 远程地址选择器
     */
    RestTemplateSelector selector;

    RestTemplate template;

    RTPTProperties config;

    public AdminCenterSource(RTPTProperties config, RestTemplateSelector restTemplateSelector) {
        this.config = config;
        this.selector = restTemplateSelector;
        this.template = this.selector.init();
    }

    @Override
    public String get(String environment, String key) {
        String url = url("/api/property/{key}/");
        Map<String, Object> params = Collections.singletonMap("env", config.getEnvironment());
        return getConfigCenterProperty(url, params, key);
    }

    @Override
    public Map<String, String> loadAll(String environment, String prefix) {
        String url = url("/api/properties");

        Map<String, Object> params = new HashMap<>();
        if (StringUtils.hasText(config.getPrefix())) {
            params.put("prefix", config.getPrefix());
        }
        if (StringUtils.hasText(config.getEnvironment())) {
            params.put("env", config.getEnvironment());
        }
        return getConfigCenterProperties(url, params);
    }

    protected String url(String uri) {
        String url = selector.select(template);
        return String.format("%s%s%s", url, config.getCenter().getContextPath(), uri);
    }

    @Retryable
    private Map<String, String> getConfigCenterProperties(String url, Map<String, Object> params) {
        return template.getForObject(url, Map.class, params);
    }


    @Retryable
    private String getConfigCenterProperty(String url, Map<String, Object> params, Object... uriVariables) {
        return template.getForObject(url, String.class, uriVariables);
    }

}
